package surreal.triviamaster.beans;

import java.util.Arrays;

import android.util.Log;
import surreal.triviamaster.utilities.LevenshteinDistance;
import surreal.triviamaster.utilities.TriviaMasterApplication;
import surreal.triviamaster.utilities.Utilities;

public class Question {
	private int id;
	private String question;
	private Answer[] aAs;
	private Category[] cats;
	private boolean correctlyAnswered;
	private int flag;
	private int quizIndex;
	private String guess;
	private LikelyAnswer[] fAs;
	private String hint;
	private int usedHint;
	private int usedMC;
	
	public boolean getCorrectlyAnswered() {
		return correctlyAnswered;
	}
	
	/**
	 * 
	 * @param questionId
	 * @param question
	 * @param correctlyAnswered
	 * @param quizIndex
	 * @param flagged
	 * @param guess
	 * @param usedMC 
	 * @param usedHint 
	 * @throws Exception 
	 */

	public Question(int questionId, String question, boolean correctlyAnswered, int quizIndex, 
			int flagged, String guess, String hint, int usedHint, int usedMC) throws Exception {
		if(guess.equals("")) {
			guess=" ";
		}
		if(Utilities.isValidToUpload(question)) {
			setQuestion(question);
		} else {
			System.out.println(question + " : " + Utilities.isValidToUpload(question) + " ");
			throw new Exception(TriviaMasterApplication.ERROR_INVALID_CHARACTERS + ", " + question);
		}
		this.id=questionId;
		this.correctlyAnswered=correctlyAnswered;
		this.setQuizIndex(quizIndex);
		this.setFlag(flagged);
		this.setGuess(guess);
		this.setHint(hint);
		this.setUsedHint(usedHint);
		this.setUsedMC(usedMC);
	}

	private void setHint(String hint) {
		System.out.println("Hint:  " + hint);
		System.out.println("Hint2:  " + hint==null);
		if(hint.equals("null")) {
			this.hint="";
		} else {
			this.hint=hint;
		}
		
	}

	/*
	 * Returns true if the guess is an acceptable guess within certain bounds
	 */
	public boolean guess(String guess) {
		//walk through all acceptable answers
		for(int x=0;x<aAs.length;x++){
			//compute distance
			int distance = LevenshteinDistance.computeLevenshteinDistance(guess.toLowerCase(), aAs[x].getAnswer().toLowerCase());
			int acceptableDistance = (int) (aAs[x].getAnswer().length()*.25);
			Log.d("Question", "Distance: "+ distance + " AcceptableDistance:  " + acceptableDistance);
			
			//if distance is within the acceptable range
			if(distance<=acceptableDistance)
				return true;
		}
		return false;
	}
	
	public int getId() {
		return id;
	}

	public String getQuestion() {
		return question;
	}

	private void setQuestion(String question) {
		this.question = question;
	}

	public String getAcceptableAnswersSplit() {
		String toRet="";
		for(int i=0;i<aAs.length-1;i++) {
			toRet+=aAs[i].getAnswer()+";";
		}
		toRet+=aAs[aAs.length-1].getAnswer();
		return toRet;
	}
	
	public String getFalseAnswersSplitId() {
		String toRet="";
		for(int i=0;i<fAs.length-1;i++) {
			toRet+=fAs[i].getAnswerid()+"<>";
			if(guess.equals(fAs[i].getAnswer())) {
				toRet+="true;";
			} else {
				toRet+="false;";
			}
		}
		//if there are fAs
		if(fAs.length>0) {
			toRet+=fAs[fAs.length-1].getAnswerid()+"<>";
			if(guess.equals(fAs[fAs.length-1].getAnswer())) {
				toRet+="true";
			} else {
				toRet+="false";
			} 
		}
		return toRet;
	}

	public String getCategoriesSplit() {
		String toRet="";
		for(int i=0;i<cats.length;i++) {
			toRet+=cats[i].getId();
		}
		toRet+=aAs[cats.length-1].getId();
		return toRet;
	}

	@Override
	public String toString() {
		return "Question [id=" + id + ", question=" + question + ", aAs="
				+ Arrays.toString(aAs) + ", cats=" + Arrays.toString(cats)
				+ ", correctlyAnswered=" + correctlyAnswered + ", flag=" + flag
				+ ", quizIndex=" + quizIndex + ", guess=" + guess + ", fAs="
				+ Arrays.toString(fAs) + ", hint=" + hint + "]";
	}

	public int getFlag() {
		return flag;
	}

	public void setFlag(int flag) {
		this.flag = flag;
	}

	public int getQuizIndex() {
		return quizIndex;
	}

	public void setQuizIndex(int quizIndex) {
		this.quizIndex = quizIndex;
	}
	
	/**
	 * Compares the two question
	 * @param tmp The question that is being compared
	 * @return True if the two are the same otherwise false
	 */
	public boolean equals(Question tmp){
		
		if(this.id!=tmp.getId()) {
			return false;
		}
		if(!this.question.equals(tmp.getQuestion())){
			return false;
		}
		
		if(aAs!=null&&tmp.getaAs()!=null){
			if(aAs.length!=tmp.getaAs().length){
				return false;
			}
			for(int i=0;i<aAs.length;i++){
				if(!aAs[i].getAnswer().equals(tmp.getaAs()[i].getAnswer())){
					return false;
				}
			}
		}
		
		if(cats!=null&&tmp.getCats()!=null){
			if(cats.length!=tmp.getCats().length){
				return false;
			}
			for(int i=0;i<cats.length;i++){
				if(!cats[i].getCategory().equals(tmp.getCats()[i].getCategory())){
					return false;
				}
			}
		}
		if(this.correctlyAnswered!=tmp.getCorrectlyAnswered()) {
			return false;
		}
		if(this.flag!=tmp.getFlag()) {
			return false;
		}
		if(this.quizIndex!=tmp.getQuizIndex()) {
			return false;
		}
		
		return true;
	}

	public Answer[] getaAs() {
		return aAs;
	}

	/**
	 * Sets the given aAs to this question
	 * @param aAs To be added
	 * @throws Exception Throws if there is an unacceptable character in one of the answers
	 */
	public void setaAs(Answer[] aAs) throws Exception {
		for(int i=0;i<aAs.length;i++) {
			if(Utilities.isValidToUpload(aAs[i].getAnswer())) {
				
			} else {
				throw new Exception(TriviaMasterApplication.ERROR_INVALID_CHARACTERS);
			}
		}
		this.aAs = aAs;
	}

	public Category[] getCats() {
		return cats;
	}

	public void setCats(Category[] cats) {
		this.cats = cats;
	}

	public void setId(int id) {
		this.id = id;
	}

	public void setCorrectlyAnswered(boolean correctlyAnswered) {
		this.correctlyAnswered = correctlyAnswered;
	}

	public String getGuess() {
		return guess;
	}

	public void setGuess(String guess) {
		this.guess = guess;
	}

	public void setfAs(LikelyAnswer[] fAs) {
		this.fAs=fAs;
	}
	
	public Answer[] getfAs() {
		return fAs;
	}

	public String getHint() {
		return hint;
	}

	public int getUsedHint() {
		return usedHint;
	}

	public void setUsedHint(int usedHint) {
		this.usedHint = usedHint;
	}

	public int getUsedMC() {
		return usedMC;
	}

	public void setUsedMC(int usedMC) {
		this.usedMC = usedMC;
	}

}
